package com.wiscamp.ninechapters.problems.domain.models.problems.answers;

import com.wiscamp.ninechapters.common.core.DateTimeHelper;
import com.wiscamp.ninechapters.common.core.ParseHelper;
import com.wiscamp.ninechapters.problems.enums.AnswerTypes;
import com.wiscamp.ninechapters.problems.infrastructure.po.problems.QuestionAnswerPO;
import com.wiscamp.ninechapters.problems.math.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.Collection;

/**
 * 答案处理工具包
 */
public class AnswerConverter {

    private static final Logger logger = LoggerFactory.getLogger(AnswerConverter.class);

    private AnswerConverter() {
    }

    public static BooleanAnswer toBooleanAnswer(QuestionAnswerPO answer) {
        var value = new LatexBoolean(answer.getAnswerHypertext());
        return new BooleanAnswer(answer.getAnswerId(), answer.getQuestionId(), answer.getAnswerIndex(), answer.getGroupIndex(), value);
    }

    public static OptionAnswer toOptionAnswer(QuestionAnswerPO answer) {
        var value = answer.getAnswerOptionId();
        var answerBO = new OptionAnswer(answer.getAnswerId(), answer.getQuestionId(), answer.getAnswerIndex(), answer.getGroupIndex(), value);
        // answerBO.setPrefix(answer.getContentHypertext());
        return answerBO;
    }

    public static IntegerAnswer toIntegerAnswer(QuestionAnswerPO answer) {
        var value = new LatexInteger(answer.getAnswerHypertext());
        return new IntegerAnswer(answer.getAnswerId(), answer.getQuestionId(), answer.getAnswerIndex(), answer.getGroupIndex(), value);
    }

    public static DecimalAnswer toDecimalAnswer(QuestionAnswerPO answer) {
        var value = new LatexDecimal(answer.getAnswerHypertext());
        return new DecimalAnswer(answer.getAnswerId(), answer.getQuestionId(), answer.getAnswerIndex(), answer.getGroupIndex(), value);
    }

    public static PercentAnswer toPercentAnswer(QuestionAnswerPO answer) {
        var tempText = answer.getAnswerHypertext().replace("%", "");
        var value = new LatexPercent(tempText);
        return new PercentAnswer(answer.getAnswerId(), answer.getQuestionId(), answer.getAnswerIndex(), answer.getGroupIndex(), value);
    }

    public static MultipleOptionAnswer toMultipleOptionAnswer(QuestionAnswerPO answer) {
        var tempText = answer.getAnswerHypertext();
        var values = ParseHelper.parseLong(tempText, ",");
        return new MultipleOptionAnswer(answer.getAnswerId(), answer.getQuestionId(), answer.getAnswerIndex(), answer.getGroupIndex(), values);
    }

    public static FractionAnswer toFractionAnswer(QuestionAnswerPO answer) {
        var value = FractionUtils.toFraction(answer.getAnswerHypertext());
        return new FractionAnswer(answer.getAnswerId(), answer.getQuestionId(), answer.getAnswerIndex(), answer.getGroupIndex(), value);
    }

    public static RadicalNumberAnswer toRadicalNumberAnswer(QuestionAnswerPO answer) {
        var value = RadicalNumberUtils.toRadicalNumber(answer.getAnswerHypertext());
        return new RadicalNumberAnswer(answer.getAnswerId(), answer.getQuestionId(), answer.getAnswerIndex(), answer.getGroupIndex(), value);
    }

    public static LatexAnswer toLatexAnswer(QuestionAnswerPO answer) {
        var tempText = answer.getAnswerHypertext();
        var value = new LatexText(tempText, LatexTextEnum.GENERAL);
        return new LatexAnswer(answer.getAnswerId(), answer.getQuestionId(), answer.getAnswerIndex(), answer.getGroupIndex(), value);
    }

    public static ExpressionAnswer toExpressionAnswer(QuestionAnswerPO answer) {
        var tempText = answer.getAnswerHypertext();
        var expression = SentenceUtils.getExpressionLatexText(tempText);
        return new ExpressionAnswer(answer.getAnswerId(), answer.getQuestionId(), answer.getAnswerIndex(), answer.getGroupIndex(), expression);
    }

    public static EquationAnswer toEquationAnswer(QuestionAnswerPO answer) {
        var tempText = answer.getAnswerHypertext();
        return new EquationAnswer(answer.getAnswerId(), answer.getQuestionId(), answer.getAnswerIndex(), answer.getGroupIndex(), new LatexArithmeticEquation(tempText));
    }

    public static InequalityAnswer toInequalityAnswer(QuestionAnswerPO answer) {
        var tempText = answer.getAnswerHypertext();
        var inequality = new LatexArithmeticInequality(tempText);
        return new InequalityAnswer(answer.getAnswerId(), answer.getQuestionId(), answer.getAnswerIndex(), answer.getGroupIndex(), inequality);
    }

    public static TextAnswer toTextAnswer(QuestionAnswerPO answer) {
        var value = answer.getAnswerHypertext();
        return new TextAnswer(answer.getAnswerId(), answer.getQuestionId(), answer.getAnswerIndex(), answer.getGroupIndex(), value);
    }

    public static IntegerRangeAnswer toIntegerRangeAnswer(QuestionAnswerPO answer) {
        var tempText = answer.getAnswerHypertext();
        String[] array = tempText.split("-");
        BigInteger begin = ParseHelper.parseBigInteger(array[0]);
        BigInteger end = ParseHelper.parseBigInteger(array[1]);
        LatexIntegerRange range = new LatexIntegerRange(begin, end);
        return new IntegerRangeAnswer(answer.getAnswerId(), answer.getQuestionId(), answer.getAnswerIndex(), answer.getGroupIndex(), range);
    }

    public static ScienceNotationAnswer toScienceNotationAnswer(QuestionAnswerPO answer) {
        var tempText = answer.getAnswerHypertext();
        String symbol = "";
        if (tempText.startsWith("-")) {
            symbol = "-";
            tempText = tempText.substring(1);
        }

        String[] array = tempText.split("e");
        BigDecimal baseNumber = ParseHelper.parseBigDecimal(array[0]);
        int exponentiation = ParseHelper.parseInteger(array[1]);
        LatexScienceNotation value = new LatexScienceNotation(symbol, baseNumber, exponentiation);
        return new ScienceNotationAnswer(answer.getAnswerId(), answer.getQuestionId(), answer.getAnswerIndex(), answer.getGroupIndex(), value);
    }

    public static QuotientReminderAnswer toQuotientReminderAnswer(QuestionAnswerPO answer) {
        var tempText = answer.getAnswerHypertext();
        if (!tempText.contains("\\dots")) return null;
        tempText = tempText.replace("\\dots", ",");
        var values = tempText.split(",");
        if (values.length > 2 || values.length == 0) return null;
        var value1 = 0;
        var value2 = 0;
        if (values.length == 2) {
            value1 = ParseHelper.parseInteger(values[0]);
            value2 = ParseHelper.parseInteger(values[1]);
        } else {
            value1 = ParseHelper.parseInteger(values[0]);
        }
        LatexQuotientReminder quotientReminder = new LatexQuotientReminder(value1, value2);
        return new QuotientReminderAnswer(answer.getAnswerId(), answer.getQuestionId(), answer.getAnswerIndex(), answer.getGroupIndex(), quotientReminder);
    }

    public static Answer toLoopDecimalAnswer(QuestionAnswerPO answer) {
        var tempText = answer.getAnswerHypertext();
        var value = new LatexLoopDecimal(tempText);
        return new LoopDecimalAnswer(answer.getAnswerId(), answer.getQuestionId(), answer.getAnswerIndex(), answer.getGroupIndex(), value);
    }

    public static Answer toDateAnswer(QuestionAnswerPO answer) {
        var tempText = answer.getAnswerHypertext();
        LocalDate date = DateTimeHelper.parseDate(tempText);
        var value = new LatexDate(date.getYear(), date.getMonthValue(), date.getDayOfMonth());
        return new DateAnswer(answer.getAnswerId(), answer.getQuestionId(), answer.getAnswerIndex(), answer.getGroupIndex(), value);
    }

    public static Answer toTimeAnswer(QuestionAnswerPO answer) {
        var tempText = answer.getAnswerHypertext();
        LocalTime time = ParseHelper.parseTime(tempText);
        var value = new LatexTime(time.getHour(), time.getMinute(), time.getSecond());
        return new TimeAnswer(answer.getAnswerId(), answer.getQuestionId(), answer.getAnswerIndex(), answer.getGroupIndex(), value);
    }

    public static Answer toDateTimeAnswer(QuestionAnswerPO answer) {
        var tempText = answer.getAnswerHypertext();
        LocalDateTime dateTime = DateTimeHelper.parseDateTime(tempText);
        var value = new LatexDateTime(dateTime.getYear(), dateTime.getMonthValue(), dateTime.getDayOfMonth(), dateTime.getHour(), dateTime.getMinute(), dateTime.getSecond());
        return new DateTimeAnswer(answer.getAnswerId(), answer.getQuestionId(), answer.getAnswerIndex(), answer.getGroupIndex(), value);
    }

    public static Answer toRatioAnswer(QuestionAnswerPO answer) {
        var tempText = answer.getAnswerHypertext();
        String[] array = tempText.split(":");
        int numerator = ParseHelper.parseInteger(array[0]);
        int denominator = ParseHelper.parseInteger(array[1]);
        var value = new LatexRatio(numerator, denominator);
        return new RatioAnswer(answer.getAnswerId(), answer.getQuestionId(), answer.getAnswerIndex(), answer.getGroupIndex(), value);
    }

    public static Answer toProportionAnswer(QuestionAnswerPO answer) {
        var tempText = answer.getAnswerHypertext();
        String[] array1 = tempText.split("=");
        var text1 = array1[0];
        var text2 = array1[1];
        String[] values1 = text1.split(":");
        String[] values2 = text2.split(":");
        int numerator1 = ParseHelper.parseInteger(values1[0]);
        int denominator1 = ParseHelper.parseInteger(values1[1]);
        int numerator2 = ParseHelper.parseInteger(values2[0]);
        int denominator2 = ParseHelper.parseInteger(values2[1]);
        var value = new LatexProportion(numerator1, denominator1, numerator2, denominator2);
        return new ProportionAnswer(answer.getAnswerId(), answer.getQuestionId(), answer.getAnswerIndex(), answer.getGroupIndex(), value);
    }

    public static Answer toRateAnswer(QuestionAnswerPO answer) {
        var tempText = answer.getAnswerHypertext();
        var value = new LatexDecimal(tempText);
        return new RateAnswer(answer.getAnswerId(), answer.getQuestionId(), answer.getAnswerIndex(), answer.getGroupIndex(), value);
    }

    public static Answer toOperatorAnswer(QuestionAnswerPO answer, AnswerTypes answerType) {
        var tempText = answer.getAnswerHypertext();
        var value = new LatexOperator(tempText);
        return new OperatorAnswer(answer.getAnswerId(), answer.getQuestionId(), answer.getAnswerIndex(), answer.getGroupIndex(), value, answerType);
    }

    public static Answer toMeasureUnitAnswer(QuestionAnswerPO answer, AnswerTypes answerType) {
        var tempText = answer.getAnswerHypertext();
        var value = new LatexMeasureUnit(tempText);
        return new MeasureUnitAnswer(answer.getAnswerId(), answer.getQuestionId(), answer.getAnswerIndex(), answer.getGroupIndex(), value, answerType);
    }

    public static Answer toAngleDegreeAnswer(QuestionAnswerPO answer) {
        var tempText = answer.getAnswerHypertext();
        tempText = tempText.replace("^\\circ", "");
        var value = new LatexAngleDegree(tempText);
        return new AngleDegreeAnswer(answer.getAnswerId(), answer.getQuestionId(), answer.getAnswerIndex(), answer.getGroupIndex(), value);
    }

    public static Answer toVertexDenoteAnswer(QuestionAnswerPO answer) {
        var tempText = answer.getAnswerHypertext();
        var value = new LatexVertexDenote(tempText.toCharArray()[0]);
        return new VertexDenoteAnswer(answer.getAnswerId(), answer.getQuestionId(), answer.getAnswerIndex(), answer.getGroupIndex(), value);
    }

    public static Answer toAngleDenoteAnswer(QuestionAnswerPO answer) {
        var tempText = answer.getAnswerHypertext();
        tempText = tempText.replace("\\angle{", "").replace("}", "");
        var value = new LatexAngleDenote(tempText);
        return new AngleDenoteAnswer(answer.getAnswerId(), answer.getQuestionId(), answer.getAnswerIndex(), answer.getGroupIndex(), value);
    }

    public static Answer toEdgeDenoteAnswer(QuestionAnswerPO answer) {
        var tempText = answer.getAnswerHypertext();

        var array = tempText.toCharArray();
        if (array.length != 2) return null;
        var startVertex = array[0];
        var endVertex = array[1];
        var value = new LatexEdgeDenote(startVertex, endVertex);
        return new EdgeDenoteAnswer(answer.getAnswerId(), answer.getQuestionId(), answer.getAnswerIndex(), answer.getGroupIndex(), value);
    }

    public static Answer toTriangleDenoteAnswer(QuestionAnswerPO answer) {
        var tempText = answer.getAnswerHypertext();
        tempText = tempText.replace("\\triangle{", "").replace("}", "");
        var array = tempText.toCharArray();
        if (array.length != 3) return null;
        var startVertex = array[0];
        var middleVertex = array[1];
        var endVertex = array[2];
        var value = new LatexTriangleDenote(startVertex, middleVertex, endVertex);
        return new TriangleDenoteAnswer(answer.getAnswerId(), answer.getQuestionId(), answer.getAnswerIndex(), answer.getGroupIndex(), value);
    }

    public static Answer toQuadrilateralDenoteAnswer(QuestionAnswerPO answer) {
        var tempText = answer.getAnswerHypertext();
        var array = tempText.toCharArray();
        if (array.length != 4) return null;
        var startVertex = array[0];
        var middleVertex1 = array[1];
        var middleVertex2 = array[2];
        var endVertex = array[3];
        var value = new LatexQuadrangleDenote(startVertex, middleVertex1, middleVertex2, endVertex);
        return new QuadrangleDenoteAnswer(answer.getAnswerId(), answer.getQuestionId(), answer.getAnswerIndex(), answer.getGroupIndex(), value);
    }

    public static Answer toPentagonDenoteAnswer(QuestionAnswerPO answer) {
        var tempText = answer.getAnswerHypertext();
        var array = tempText.toCharArray();
        if (array.length != 5) return null;
        var startVertex = array[0];
        var middleVertex1 = array[1];
        var middleVertex2 = array[2];
        var middleVertex3 = array[3];
        var endVertex = array[4];
        var value = new LatexPentagonDenote(startVertex, middleVertex1, middleVertex2, middleVertex3, endVertex);
        return new PentagonDenoteAnswer(answer.getAnswerId(), answer.getQuestionId(), answer.getAnswerIndex(), answer.getGroupIndex(), value);
    }

    public static Answer toPointDenoteAnswer(QuestionAnswerPO answer) {
        var tempText = answer.getAnswerHypertext();
        var value = new LatexPointDenote(tempText);
        return new PointDenoteAnswer(answer.getAnswerId(), answer.getQuestionId(), answer.getAnswerIndex(), answer.getGroupIndex(), value);
    }

    public static Answer toXYPointDenoteAnswer(QuestionAnswerPO answer) {
        var tempText = answer.getAnswerHypertext();
        tempText = tempText.replace("\\left(", "").replace("(", "")
                .replace("\\right)", "").replace(")", "");
        var array = tempText.split(",");
        if (array.length != 2) return null;
        var value = new LatexXYPointDenote(array[0], array[1]);
        return new XYPointDenoteAnswer(answer.getAnswerId(), answer.getQuestionId(), answer.getAnswerIndex(), answer.getGroupIndex(), value);
    }

    public static Answer toXYZPointDenoteAnswer(QuestionAnswerPO answer) {
        var tempText = answer.getAnswerHypertext();
        tempText = tempText.replace("\\left(", "").replace("(", "")
                .replace("\\right)", "").replace(")", "");
        var array = tempText.split(",");
        if (array.length != 3) return null;
        var value = new LatexXYZPointDenote(array[0], array[1], array[2]);
        return new XYZPointDenoteAnswer(answer.getAnswerId(), answer.getQuestionId(), answer.getAnswerIndex(), answer.getGroupIndex(), value);
    }

    public static Answer toIntegerSeriesAnswer(QuestionAnswerPO answer) {
        var tempText = answer.getAnswerHypertext();
        Collection<BigInteger> values = ParseHelper.parseBigInteger(tempText, ",");
        var value = new LatexIntegerSeries(values);
        return new IntegerSeriesAnswer(answer.getAnswerId(), answer.getQuestionId(), answer.getAnswerIndex(), answer.getGroupIndex(), value);
    }

    public static Answer toSortedIntegerSeriesAnswer(QuestionAnswerPO answer) {
        var tempText = answer.getAnswerHypertext();
        Collection<BigInteger> values = ParseHelper.parseBigInteger(tempText, ",");
        var value = new LatexIntegerSeries(values);
        return new SortedIntegerSeriesAnswer(answer.getAnswerId(), answer.getQuestionId(), answer.getAnswerIndex(), answer.getGroupIndex(), value);
    }

    public static Answer toDecimalRangeAnswer(QuestionAnswerPO answer) {
        var tempText = answer.getAnswerHypertext();
        String[] array = tempText.split("-");
        BigDecimal begin = ParseHelper.parseBigDecimal(array[0]);
        BigDecimal end = ParseHelper.parseBigDecimal(array[1]);
        var range = new LatexDecimalRange(begin, end);
        return new DecimalRangeAnswer(answer.getAnswerId(), answer.getQuestionId(), answer.getAnswerIndex(), answer.getGroupIndex(), range);
    }

    public static Answer toDecimalSeriesAnswer(QuestionAnswerPO answer) {
        var tempText = answer.getAnswerHypertext();
        Collection<BigDecimal> values = ParseHelper.parseBigDecimal(tempText, ",");
        var value = new LatexDecimalSeries(values);
        return new DecimalSeriesAnswer(answer.getAnswerId(), answer.getQuestionId(), answer.getAnswerIndex(), answer.getGroupIndex(), value);
    }

    public static Answer toSortedDecimalSeriesAnswer(QuestionAnswerPO answer) {
        var tempText = answer.getAnswerHypertext();
        Collection<BigDecimal> values = ParseHelper.parseBigDecimal(tempText, ",");
        var value = new LatexDecimalSeries(values);
        return new SortedDecimalSeriesAnswer(answer.getAnswerId(), answer.getQuestionId(), answer.getAnswerIndex(), answer.getGroupIndex(), value);
    }

    public static Answer toProbabilityAnswer(QuestionAnswerPO answer) {
        var tempText = answer.getAnswerHypertext();
        var value = new LatexDecimal(tempText);
        return new ProbabilityAnswer(answer.getAnswerId(), answer.getQuestionId(), answer.getAnswerIndex(), answer.getGroupIndex(), value);
    }

    public static Answer toEquationSolutionAnswer(QuestionAnswerPO answer) {
        var tempText = answer.getAnswerHypertext();
        var equationSolution = LatexEquationSolution.parseEquationSolution(tempText);
        return new EquationSolutionAnswer(answer.getAnswerId(), answer.getQuestionId(), answer.getAnswerIndex(), answer.getGroupIndex(), equationSolution);
    }

    public static Answer toInequalitySolutionAnswer(QuestionAnswerPO answer) {
        var tempText = answer.getAnswerHypertext();
        var inequalitySolution = LatexInequalitySolution.parseInequalitySolution(tempText);
        return new InequalitySolutionAnswer(answer.getAnswerId(), answer.getQuestionId(), answer.getAnswerIndex(), answer.getGroupIndex(), inequalitySolution);
    }
}
